Descrizione |
---|
Questa macro crea una griglia a nido d'ape parametrica. Le proprietà parametriche sono contenute in un foglio di calcolo. Puoi anche cambiare l'oggetto base per la griglia a nido d'ape per ottenere altri array interessanti, come questa cassa d'uovo cambiando il oggetto esagonale di base con un ellissoide a forma di uovo. L'inclusione del raggio esagonale, la separazione tra esagoni, ecc., può essere modificata tramite un foglio di calcolo incluso. Versione macro: 2020.10.30 Ultima modifica: 2020-10-30 Versione FreeCAD: 0.17 é superiore Download: ToolBar Icon Autore: TheMarkster |
Autore |
TheMarkster |
Download |
ToolBar Icon |
Link |
Raccolta di macro Come installare le macro Personalizzare la toolbar |
Versione macro |
2020.10.30 |
Data ultima modifica |
2020-10-30 |
Versioni di FreeCAD |
0.17 é superiore |
Scorciatoia |
Nessuna |
Vedere anche |
Nessuno |
Questa macro crea una griglia a nido d'ape parametrica. Le proprietà parametriche sono contenute in un foglio di calcolo.
Puoi anche cambiare l'oggetto base per la griglia a nido d'ape per ottenere altri array interessanti, come questa cassa per le uova cambiando l'oggetto esagonale di base con un ellissoide a forma di uovo:
Macro_FCHoneycombMaker.FCMacro
# -*- coding: utf-8 -*- """ *************************************************************************** * Copyright (c) 2018-2019 <TheMarkster> * * * * This file is a supplement to the FreeCAD CAx development system. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License (LGPL) * * as published by the Free Software Foundation; either version 2 of * * the License, or (at your option) any later version. * * * * This software is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License at http://www.gnu.org/licenses * * for more details. * * * * For more information about the GNU Library General Public License * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307 USA * * * *************************************************************************** """ """ FCHoneycombMaker This is a macro to aid in creation of a honeycomb grid. Parameters, including hexagon radius, separation between hexagons, etc., can be modified via an included spreadsheet. """ __title__ = "FCHoneycombMaker" __author__ = "TheMarkster" __url__ = "https://github.com/mwganson/FCHoneycombMaker" __Wiki__ = "https://github.com/mwganson/FCHoneycombMaker/blob/master/README.md" __date__ = "2020.10.30" #year.month.date __version__ = __date__ import FreeCAD import math import Part,Draft,DraftTools from PySide import QtCore, QtGui import ProfileLib.RegularPolygon import Sketcher RADIUS = 2 SEPARATION = .25 PLATE_WIDTH = 20 PLATE_LENGTH = 55 PLATE_HEIGHT = 5 FreeCAD.Console.PrintMessage ('\nFCHoneycombMaker v'+__version__+'\n') def makeHexagonSketch(sketchName): #would use the polygon tool, but is buggy and sometimes creates squares instead of hexagons, so the manual way sketch = App.ActiveDocument.getObject(sketchName) #we just place the vertices any old where and then constrain them into place later sketch.addGeometry(Part.LineSegment(App.Vector(-2.000000,1.448548,0),App.Vector(0.500515,2.469759,0)),False) sketch.addGeometry(Part.LineSegment(App.Vector(0.500515,2.469759,0),App.Vector(2.000000,1.696951,0)),False) sketch.addConstraint(Sketcher.Constraint('Coincident',0,2,1,1)) sketch.addGeometry(Part.LineSegment(App.Vector(2.000000,1.696951,0),App.Vector(2.736140,-0.676675,0)),False) sketch.addConstraint(Sketcher.Constraint('Coincident',1,2,2,1)) sketch.addGeometry(Part.LineSegment(App.Vector(2.736140,-0.676675,0),App.Vector(1.000000,-2.415493,0)),False) sketch.addConstraint(Sketcher.Constraint('Coincident',2,2,3,1)) sketch.addGeometry(Part.LineSegment(App.Vector(1.000000,-2.415493,0),App.Vector(-3.000000,-1.000000,0)),False) sketch.addConstraint(Sketcher.Constraint('Coincident',3,2,4,1)) sketch.addGeometry(Part.LineSegment(App.Vector(-3.000000,-1.000000,0),App.Vector(-2.000000,1.365748,0)),False) sketch.addConstraint(Sketcher.Constraint('Coincident',4,2,5,1)) sketch.addConstraint(Sketcher.Constraint('Coincident',5,2,0,1)) sketch.addGeometry(Part.Circle(App.Vector(0.000000,0.000000,0),App.Vector(0,0,1),3.535498),False) #construction circle sketch.addConstraint(Sketcher.Constraint('Coincident',6,3,-1,1)) sketch.addConstraint(Sketcher.Constraint('Radius',6,3.535498)) sketch.setDatum(7,App.Units.Quantity('2.000000 mm')) sketch.addConstraint(Sketcher.Constraint('PointOnObject',4,2,6)) #constrain all vertices to the circumference sketch.addConstraint(Sketcher.Constraint('PointOnObject',0,1,6)) sketch.addConstraint(Sketcher.Constraint('PointOnObject',0,2,6)) sketch.addConstraint(Sketcher.Constraint('PointOnObject',1,2,6)) sketch.addConstraint(Sketcher.Constraint('PointOnObject',2,2,6)) sketch.addConstraint(Sketcher.Constraint('PointOnObject',3,2,6)) sketch.toggleConstruction(6) sketch.addConstraint(Sketcher.Constraint('Equal',5,0)) #set all lines equal sketch.addConstraint(Sketcher.Constraint('Equal',0,1)) sketch.addConstraint(Sketcher.Constraint('Equal',1,2)) sketch.addConstraint(Sketcher.Constraint('Equal',2,3)) sketch.addConstraint(Sketcher.Constraint('Equal',3,4)) sketch.addConstraint(Sketcher.Constraint('Horizontal',0)) #make one of them horizontal sketch.setExpression('Constraints[7]', u'EditMe.radius') if not App.ActiveDocument: App.newDocument() if hasattr(App.ActiveDocument,"EditMe"): raise StandardError("FCHoneycombMaker Error: Please run only once per document. Create a new document and try again.\n") worksheet = App.ActiveDocument.addObject("Spreadsheet::Sheet", "EditMe") worksheet.setColumnWidth('A',150) set = worksheet.set worksheet.mergeCells('A11:G25') msg1 = """Instructions: You should only run the macro once unless you want to start again from scratch. Edit the values in column B to define your honeycomb. You can also edit the objects (plate, arrays, etc.), but it's probably better to do all the editing here in the spreadsheet at least until you get it more or less like you want it before doing some final tweaking directly on the objects. Hexagon radius -- the circumradius of the individual hexagons (circle with each vertex on its circumference). Hexagon separation -- distance between each hexagon, the thickness of the grid produced after cutting the hexagons from the plate. Plate dimensions -- sets the dimensions of the plate out of which the honeycomb can be cut. These values are used to calculate the countX and countY variables. You can delete the plate object if you wish to apply the hexagon arrays to a different structure. Tweak X,Y,Z -- Edit these to move both hexagon arrays independently of the plate object, for example to center the arrays inside the plate. CountX and CountY -- number of hexagons in the 2 arrays. These are calculated based on the plate size, radius of hexagons, and separation between them, but you will probably want to modify these manually. Just remember if you modify them you are replacing the formulas in those cells with immediate values, and thus they won't be recalulated for you if other changes are made. If you would prefer a round plate, simply delete the plate object and replace it with a cylinder, and then use the Tweak values and countX and countY variables to arrange the hexagon arrays to your liking. """ set('A13', msg1) aliases={'radius':'B2', 'separation':'B3', 'width':'B4', 'length':'B5', 'height':'B6', 'tweakX':'B8','tweakY':'B9','tweakZ':'B10', 'xInterval':'E2', 'yInterval':'E3', 'firstX':'E4', 'firstY':'E5','countX':'E6', 'countY':'E7','array2XPos':'E8','array2YPos':'E9', } for k,v in aliases.items(): worksheet.setAlias(v,k) set('A1', 'User Variables') set('D1','Calculated Values') set('A2', 'Hexagon Radius:') set(aliases['radius'], str(RADIUS)) set('A3', 'Hexagon Separation:') set(aliases['separation'], str(SEPARATION)) set('A4', 'Grid Width:') set(aliases['width'], str(PLATE_WIDTH)) set('A5', 'Grid Length:') set(aliases['length'], str(PLATE_LENGTH)) set('A6', 'Grid Height:') set(aliases['height'], str(PLATE_HEIGHT)) set('A8', 'Tweak X:') set(aliases['tweakX'],u'0') set('A9', 'Tweak Y:') set(aliases['tweakY'],u'0') set('A10', 'Tweak Z:') set(aliases['tweakZ'],u'0') set('D2','X Interval:') set(aliases['xInterval'],'=2*sin(60deg)*(B2*2+(B3-0.267949*B2))') set('D3', 'Y Interval:') set(aliases['yInterval'], '=2*B2+(B3-0.267949*B2)' ) set('D4', 'First X:') set(aliases['firstX'], '=B2') set('D5', 'First Y:') set(aliases['firstY'], '=B2') set('D6', 'Count X:') set(aliases['countX'], '=round((B5) / E2) + 2') set('D7', 'Count Y:') set(aliases['countY'], '=round((B4) / E3) + 2') set ('D8', 'Array2 XPos:') set (aliases['array2XPos'], '=sin(60deg)*(B2*2+B3-0.26794899999999999*B2)') set ('D9', 'Array2 YPos:') set (aliases['array2YPos'],'=E3/2') #xInterval = float(worksheet.getContents(aliases['xInterval'])) xInterval = 2*math.sin(math.pi/180.0*60)*(RADIUS*2+(SEPARATION-0.267949)) yInterval = 2*RADIUS+(SEPARATION-0.267949) #yInterval = float(worksheet.getContents(aliases['yInterval'])) firstX = RADIUS firstY = RADIUS countY = int((PLATE_LENGTH) / yInterval) countX = int((PLATE_WIDTH) / xInterval) App.ActiveDocument.addObject("Part::RegularPolygon","HoneycombHexagon") App.ActiveDocument.HoneycombHexagon.Polygon=6 App.ActiveDocument.HoneycombHexagon.setExpression('Circumradius','EditMe.radius') hexagonObject = App.ActiveDocument.getObject("HoneycombHexagon") Gui.ActiveDocument.getObject("HoneycombHexagon").Visibility=False extrudedHexagonObject = App.ActiveDocument.addObject('Part::Extrusion', 'ExtrudedHexagon') extrudedHexagonObject.Base = hexagonObject extrudedHexagonObject.setExpression('LengthFwd','EditMe.height') extrudedHexagonObject.Solid=True #extrudedHexagonObject.Placement=App.Placement(App.Vector(firstX,firstY,0),App.Rotation(0,0,0),App.Vector(0,0,0)) extrudedHexagonObject.setExpression('Placement.Base.x','EditMe.firstX+EditMe.tweakX') extrudedHexagonObject.setExpression('Placement.Base.y','EditMe.firstY+EditMe.tweakY') extrudedHexagonObject.setExpression('Placement.Base.z', 'EditMe.tweakZ') xvector = App.Vector(xInterval,0,0) yvector = App.Vector(0, yInterval,0) if not hasattr(Draft,"make_ortho_array"): row1Array = Draft.makeArray(extrudedHexagonObject, xvector,yvector,countX,countY,name="HoneycombArray1") row2Array = Draft.makeArray(extrudedHexagonObject, xvector,yvector,countX,countY,name="HoneycombArray2") else: row1Array = Draft.make_ortho_array(extrudedHexagonObject, v_x=xvector,v_y=yvector,n_x=countX,n_y=countY,use_link=False) row2Array = Draft.make_ortho_array(extrudedHexagonObject, v_x=xvector,v_y=yvector,n_x=countX,n_y=countY,use_link=False) App.ActiveDocument.recompute() row2Array.Placement = App.Placement(App.Vector(math.sin(60*math.pi/180.0)*(RADIUS*2+(SEPARATION-0.267949)),yInterval,0),App.Rotation(0,0,0),App.Vector(0,0,0)) #row2Array.setExpression('Placement.Base.x','sin(60deg) * (EditMe.radius * 2 + (EditMe.separation-0.267949*EditMe.radius))') row2Array.setExpression('Placement.Base.x','EditMe.array2XPos') #row2Array.setExpression('Placement.Base.y','EditMe.yInterval/2.0') row2Array.setExpression('Placement.Base.y','EditMe.array2YPos') row1Array.setExpression('IntervalX.x','EditMe.xInterval') row1Array.setExpression('IntervalY.y','EditMe.yInterval') row1Array.setExpression('NumberX','EditMe.countX') row1Array.setExpression('NumberY','EditMe.countY') row2Array.setExpression('IntervalX.x','EditMe.xInterval') row2Array.setExpression('IntervalY.y','EditMe.yInterval') row2Array.setExpression('NumberX','EditMe.countX') row2Array.setExpression('NumberY','EditMe.countY') App.activeDocument().addObject("Part::MultiFuse","Fused_Arrays") #App.activeDocument().Fused_Arrays.Shapes = [App.activeDocument().HoneycombArray1,App.activeDocument().HoneycombArray2,] App.activeDocument().Fused_Arrays.Shapes = [row1Array,row2Array,] if not hasattr(Draft,"make_ortho_array"): Gui.activeDocument().HoneycombArray1.Visibility=False Gui.activeDocument().HoneycombArray2.Visibility=False else: row1Array.Visibility=False row2Array.Visibility=False window = QtGui.QApplication.activeWindow() items=('Part Design Workbench Body','Part Workbench Object') item,ok = QtGui.QInputDialog.getItem(window, "Select object type", "Select your object type. It can be a Part Design body or a Part Cut object.", items, 0, False) if ok: if item == items[0]: #PD Body App.ActiveDocument.addObject("Part::Plane", "HoneycombPlane") App.ActiveDocument.HoneycombPlane.setExpression('Length', u'EditMe.length') App.ActiveDocument.HoneycombPlane.setExpression('Width', u'EditMe.width') App.ActiveDocument.HoneycombPlane.setExpression('Placement.Base.x', u'EditMe.array2XPos + EditMe.radius * 2') App.ActiveDocument.HoneycombPlane.setExpression('Placement.Base.y', u'EditMe.array2YPos + EditMe.radius * 2') App.activeDocument().addObject("Part::Cut","BaseFeatureFace") App.ActiveDocument.getObject("BaseFeatureFace").ViewObject.Visibility=False App.activeDocument().BaseFeatureFace.Base = App.activeDocument().HoneycombPlane App.activeDocument().BaseFeatureFace.Tool = App.activeDocument().Fused_Arrays Gui.activeDocument().HoneycombPlane.Visibility=False Gui.activeDocument().Fused_Arrays.Visibility=False App.ActiveDocument.recompute() App.activeDocument().addObject('PartDesign::Body','HoneycombBody') App.activeDocument().HoneycombBody.BaseFeature = App.activeDocument().BaseFeatureFace Gui.activeView().setActiveObject('pdHoneycombBody', App.activeDocument().HoneycombBody) App.activeDocument().HoneycombBody.newObject("PartDesign::Pad","HoneycombPad") App.activeDocument().HoneycombPad.Profile = (App.activeDocument().BaseFeature, ["Face1"]) App.activeDocument().HoneycombPad.Length = 10.0 App.ActiveDocument.recompute() Gui.activeDocument().setEdit('HoneycombPad', 0) Gui.activeDocument().hide("BaseFeature") App.ActiveDocument.HoneycombPad.setExpression('Length', u'EditMe.height') App.ActiveDocument.HoneycombPad.Length2 = 100.000000 App.ActiveDocument.HoneycombPad.Type = 0 App.ActiveDocument.HoneycombPad.UpToFace = None App.ActiveDocument.HoneycombPad.Reversed = 0 App.ActiveDocument.HoneycombPad.Midplane = 0 App.ActiveDocument.HoneycombPad.Offset = 0.000000 App.ActiveDocument.recompute() Gui.activeDocument().resetEdit() else: #Part object #plate = Part.makeBox(PLATE_WIDTH,PLATE_LENGTH,PLATE_HEIGHT) #plate = Part.makeBox(worksheet.B4, worksheet.B5, worksheet.B6) App.ActiveDocument.addObject("Part::Box", "Plate") plateObject = App.ActiveDocument.getObject("Plate") App.ActiveDocument.Plate.setExpression('Length', u'EditMe.length') App.ActiveDocument.Plate.setExpression('Width', u'EditMe.width') App.ActiveDocument.Plate.setExpression('Height', u'EditMe.height') App.ActiveDocument.Plate.setExpression('Placement.Base.x', u'EditMe.array2XPos + EditMe.radius * 2') App.ActiveDocument.Plate.setExpression('Placement.Base.y', u'EditMe.array2YPos + EditMe.radius * 2') App.activeDocument().addObject("Part::Cut","HoneycombGrid") App.activeDocument().HoneycombGrid.Base = App.activeDocument().Plate App.activeDocument().HoneycombGrid.Tool = App.activeDocument().Fused_Arrays Gui.activeDocument().Plate.Visibility=False Gui.activeDocument().Fused_Arrays.Visibility=False App.ActiveDocument.recompute() Gui.SendMsgToActiveView("ViewFit")
Completa documentazione su https://github.com/mwganson/FCHoneycombMaker
Argomento dell'annuncio della funzione nella conversazione del forum FCHoneycombMaker Macro
Altra macro a nido d'ape simile Honeycomb Array
2019-07-04 : prima